# page/detail.py
import os
import time
from datetime import datetime, timedelta

from flask import Blueprint, render_template, redirect, request, url_for, current_app, jsonify
from config import db
from models import House, User
from sqlalchemy import func

# Blueprint 名称应和 app.py 中注册的一致（通常是 'detail_page'）
detail_page = Blueprint('detail_page', __name__)

# -----------------------
# 工具：解析 image 字段得到可用的 static URL（uploads/images/img 回退）
# -----------------------
def resolve_image_url_for_item(img_field_value):
    static_root = current_app.static_folder
    try:
        if img_field_value and isinstance(img_field_value, str) and img_field_value.strip().lower().startswith(('http://', 'https://')):
            return img_field_value.strip()
    except Exception:
        pass

    if img_field_value and isinstance(img_field_value, str):
        name = os.path.basename(img_field_value.strip())
        if os.path.exists(os.path.join(static_root, 'uploads', name)):
            return url_for('static', filename=f'uploads/{name}')
        if os.path.exists(os.path.join(static_root, 'images', name)):
            return url_for('static', filename=f'images/{name}')
        if os.path.exists(os.path.join(static_root, 'img', name)):
            return url_for('static', filename=f'img/{name}')

    # 回退默认图
    defaults = [
        ('uploads', 'default_house.jpg'),
        ('images', 'default_house.jpg'),
        ('img', 'house-bg1.jpg'),
    ]
    for folder, fname in defaults:
        if os.path.exists(os.path.join(static_root, folder, fname)):
            return url_for('static', filename=f'{folder}/{fname}')
    return url_for('static', filename='img/house-bg1.jpg')


# -----------------------
# 详情页视图：/house/<hid>
# - 渲染详情模板
# - 写入 view log 到 house_view_log（若表存在）
# -----------------------
@detail_page.route('/house/<int:hid>')
def index(hid):
    # 查询房源
    house = House.query.get(hid)
    if not house:
        return redirect('/')

    # 解析设施
    facilities = house.facilities or ''
    facilities_list = facilities.split('-') if facilities else []

    # 推荐：同地址按热度
    try:
        recommend_list = House.query.filter(House.address == house.address).order_by(House.page_views.desc()).limit(6).all()
    except Exception:
        recommend_list = []

    # 增加浏览次数（如果模型有该方法）
    try:
        if hasattr(house, 'increment_view_count'):
            house.increment_view_count()
        else:
            # fallback: try to increment field and commit
            try:
                house.page_views = (house.page_views or 0) + 1
                db.session.add(house)
                db.session.commit()
            except Exception:
                db.session.rollback()
    except Exception:
        pass

    # 记录访问日志到 house_view_log（尽量不要影响页面正常渲染）
    try:
        ts_now = int(time.time())
        # raw sql insert；确保你已手动创建表 house_view_log (见 templates/db sql)
        db.session.execute("INSERT INTO house_view_log (house_id, ts) VALUES (:hid, :ts)", {'hid': hid, 'ts': ts_now})
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        # 不要让日志写失败影响页面显示，打印供调试
        # print("insert view log failed:", e)

    # 获取用户和收藏状态（cookie 名称 'name'）
    name = request.cookies.get('name')
    user = None
    try:
        if name:
            user = User.query.filter(User.name == name).first()
    except Exception:
        user = None

    collection_status = False
    if user:
        collect_id = user.collect_id or ''
        collect = collect_id.split(',') if collect_id else []
        collection_status = str(hid) in collect

    # 解析图片 URL 给模板使用
    try:
        house.image_url = resolve_image_url_for_item(getattr(house, 'image', None))
    except Exception:
        house.image_url = url_for('static', filename='img/house-bg1.jpg')

    return render_template('house_detail.html',
                           house=house,
                           facilities=facilities_list,
                           recommend=recommend_list,
                           collection=collection_status)


# -----------------------
# 收藏切换（AJAX POST）: /collect/<hid>
# -----------------------
@detail_page.route('/collect/<int:hid>', methods=['POST'])
def toggle_collect(hid):
    name = request.cookies.get('name')
    if not name:
        return jsonify({'code': 0, 'msg': '请先登录', 'collected': False}), 401

    user = User.query.filter(User.name == name).first()
    if not user:
        return jsonify({'code': 0, 'msg': '用户不存在', 'collected': False}), 404

    collect_id = user.collect_id or ''
    collect = [c for c in collect_id.split(',') if c] if collect_id else []

    hid_str = str(hid)
    if hid_str in collect:
        collect.remove(hid_str)
        collected = False
    else:
        collect.append(hid_str)
        collected = True

    user.collect_id = ','.join(collect)
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 0, 'msg': '保存失败', 'error': str(e), 'collected': False}), 500

    return jsonify({'code': 1, 'msg': 'success', 'collected': collected})


# -----------------------
# Analytics API：/house/<hid>/analytics
# 返回：timeseries (最近 N 天), summary, price_compare
# -----------------------
@detail_page.route('/house/<int:hid>/analytics')
def house_analytics(hid):
    house = House.query.get(hid)
    if not house:
        return jsonify({'status': 'error', 'msg': 'House not found'}), 404

    N = current_app.config.get('ANALYTICS_DAYS', 30)
    end_date = datetime.utcnow().date()
    start_date = end_date - timedelta(days=N-1)

    timeseries = []
    try:
        uri = current_app.config.get('SQLALCHEMY_DATABASE_URI', '').lower()
        records = []
        if 'sqlite' in uri:
            sql = """
            SELECT DATE(datetime(ts, 'unixepoch')) as d, COUNT(1) as cnt
            FROM house_view_log
            WHERE house_id = :hid AND DATE(datetime(ts, 'unixepoch')) BETWEEN :start AND :end
            GROUP BY DATE(datetime(ts, 'unixepoch'))
            ORDER BY d ASC
            """
            res = db.session.execute(sql, {'hid': hid, 'start': start_date.isoformat(), 'end': end_date.isoformat()})
            for row in res:
                records.append({'date': row['d'], 'views': int(row['cnt'])})
        else:
            # MySQL style
            sql = """
            SELECT DATE(FROM_UNIXTIME(ts)) as d, COUNT(1) as cnt
            FROM house_view_log
            WHERE house_id = %s AND DATE(FROM_UNIXTIME(ts)) BETWEEN %s AND %s
            GROUP BY DATE(FROM_UNIXTIME(ts))
            ORDER BY d ASC
            """
            res = db.session.execute(sql, (hid, start_date.isoformat(), end_date.isoformat()))
            for row in res:
                records.append({'date': str(row[0]), 'views': int(row[1])})

        date_map = {r['date']: r['views'] for r in records}
        for i in range(N):
            d = (start_date + timedelta(days=i)).isoformat()
            timeseries.append({'date': d, 'views': date_map.get(d, 0)})
    except Exception as e:
        # 回退：用 house.page_views 生成示例序列
        # print("analytics timeseries error:", e)
        total = int(getattr(house, 'page_views', 0) or 0)
        per = max(1, total // N) if total > 0 else 0
        for i in range(N):
            date = (start_date + timedelta(days=i)).isoformat()
            v = per + (i % 5)
            timeseries.append({'date': date, 'views': v})

    # summary
    total_views = int(getattr(house, 'page_views', 0) or 0)
    last_7 = sum([t['views'] for t in timeseries[-7:]]) if len(timeseries) >= 7 else sum([t['views'] for t in timeseries])

    # rank in region (按 address 完全匹配的排序)
    region_rank = None
    try:
        if hasattr(House, 'address') and getattr(house, 'address', None):
            q = House.query.filter(House.address == house.address).order_by(House.page_views.desc()).all()
            rank = 1
            for h in q:
                if h.id == house.id:
                    region_rank = rank
                    break
                rank += 1
    except Exception:
        region_rank = None

    # price compare
    def median_price(list_objs):
        vals = []
        for hh in list_objs:
            try:
                vals.append(int(getattr(hh, 'price', 0) or 0))
            except Exception:
                pass
        if not vals:
            return None
        vals.sort()
        m = len(vals)
        return vals[m//2] if m % 2 == 1 else (vals[m//2 - 1] + vals[m//2]) // 2

    community_median = None
    region_median = None
    try:
        if hasattr(House, 'community') and getattr(house, 'community', None):
            community_q = House.query.filter(House.community == house.community).all()
            community_median = median_price(community_q)
    except Exception:
        community_median = None
    try:
        if hasattr(House, 'address') and getattr(house, 'address', None):
            region_key = str(house.address).split('-')[0] if house.address else None
            if region_key:
                region_q = House.query.filter(House.address.like(f"%{region_key}%")).all()
                region_median = median_price(region_q)
    except Exception:
        region_median = None

    price_compare = {
        'current_price': int(getattr(house, 'price', 0) or 0),
        'community_median': community_median,
        'region_median': region_median
    }

    data = {
        'timeseries': timeseries,
        'summary': {
            'total_views': total_views,
            'last_7_days': last_7,
            'rank_in_region': region_rank
        },
        'price_compare': price_compare
    }
    return jsonify({'status': 'ok', 'data': data})


# 若需要，保留一个小过滤器
def deal_none(word):
    if not word:
        return '暂无信息'
    return word

detail_page.add_app_template_filter(deal_none, 'dealNone')
